package com.snail.controller;

import com.snail.common.DeleteRequest;
import com.snail.exception.BusinessException;
import com.snail.exception.ErrorCode;
import com.snail.model.dto.UploadFileParamsDto;
import com.snail.model.dto.UploadFileResultDto;
import com.snail.model.pojo.BizMediaFile;
import com.snail.model.vo.VideoPageListVo;
import com.snail.response.BaseResponse;
import com.snail.response.PageResponse;
import com.snail.service.BizMediaFileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

/**
 * @author Monica
 * @description 处理文件的Controller
 * @date 2025/7/15 14:08
 */
@RestController
@RequestMapping("/file")
@AllArgsConstructor
@Slf4j
@CrossOrigin
public class BizMediaFileController {

    @Resource
    private final BizMediaFileService bizMediaFileService;

    /**
     * 上传图片
     *
     * @param file 上传的图片文件
     * @return 包含上传结果的响应
     * @throws BusinessException 当文件上传过程中发生错误时抛出
     */
    @Operation(summary = "上传图片", description = "上传图片接口")
    @PostMapping(path = "/uploadPic", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public BaseResponse<UploadFileResultDto> uploadPic(
            @RequestParam("file") MultipartFile file) {

        // 参数校验
        if (file == null || file.isEmpty()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件不能为空");
        }
        // 准备上传参数
        UploadFileParamsDto uploadFileParamsDto = new UploadFileParamsDto();
        uploadFileParamsDto.setFileType(2);
        uploadFileParamsDto.setFileName(file.getOriginalFilename());
        uploadFileParamsDto.setFileSize(file.getSize());
        // 创建临时文件并上传
        File tempFile = null;
        try {
            // 创建临时文件（自动删除）
            tempFile = File.createTempFile("minio_", ".temp");
            // 将上传文件内容复制到临时文件
            file.transferTo(tempFile);

            // 执行上传
            return bizMediaFileService.uploadFile(uploadFileParamsDto, tempFile.getAbsolutePath());
        } catch (IOException e) {
            if (tempFile != null) {
                log.error("文件上传失败: {}", tempFile.getAbsolutePath(), e);
            }
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败");
        } finally {
            // 确保临时文件被删除
            if (tempFile != null && tempFile.exists()) {
                try {
                    Files.delete(tempFile.toPath());
                } catch (IOException e) {
                    log.error("删除临时文件失败: {}", tempFile.getAbsolutePath(), e);
                }
            }
        }
    }

    /**
     * 上传文档
     *
     * @param file 上传的文档文件
     * @return 包含上传结果的响应
     * @throws BusinessException 当文件上传过程中发生错误时抛出
     */
    @Operation(summary = "上传文档", description = "上传文档")
    @PostMapping(path = "/uploadDoc", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public BaseResponse<UploadFileResultDto> uploadDoc(
            @RequestParam("file") MultipartFile file) {

        // 参数校验741
        if (file == null || file.isEmpty()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件不能为空");
        }
        // 准备上传参数
        UploadFileParamsDto uploadFileParamsDto = new UploadFileParamsDto();
        uploadFileParamsDto.setFileType(3);
        uploadFileParamsDto.setFileName(file.getOriginalFilename());
        uploadFileParamsDto.setFileSize(file.getSize());
        // 创建临时文件并上传
        File tempFile = null;
        try {
            // 创建临时文件（自动删除）
            tempFile = File.createTempFile("minio_", ".temp");
            // 将上传文件内容复制到临时文件
            file.transferTo(tempFile);

            // 执行上传
            return bizMediaFileService.uploadFile(uploadFileParamsDto, tempFile.getAbsolutePath());
        } catch (IOException e) {
            if (tempFile != null) {
                log.error("文件上传失败: {}", tempFile.getAbsolutePath(), e);
            }
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败");
        } finally {
            // 确保临时文件被删除
            if (tempFile != null && tempFile.exists()) {
                try {
                    Files.delete(tempFile.toPath());
                } catch (IOException e) {
                    log.error("删除临时文件失败: {}", tempFile.getAbsolutePath(), e);
                }
            }
        }
    }



    /**
     * 删除文件
     * @param fileMd5 文件md5
     * @return 删除结果
     */
    @Operation(summary = "删除文件", description = "删除文件")
    @PostMapping("/deleteFile")
    public BaseResponse<Boolean> deleteFile(String fileMd5) {
        return bizMediaFileService.deleteFile(fileMd5);
    }




    @Operation(summary = "文件上传前检查文件", description = "文件上传前检查文件是否存在")
    @PostMapping("/checkFile")
    public BaseResponse<Boolean> checkFile(@RequestParam("fileMd5") String fileMd5) {
        return bizMediaFileService.checkFile(fileMd5);
    }

    @Operation(summary = "分块文件上传前的检测", description = "分块文件上传前的检测")
    @PostMapping("/checkChunk")
    public BaseResponse<Boolean> checkChunk(@RequestParam("fileMd5") String fileMd5,
                                            @RequestParam("chunk") int chunk) throws Exception {
        return bizMediaFileService.checkChunk(fileMd5, chunk);
    }

    @Operation(summary = "上传分块文件", description = "用于大文件分块上传，需提供文件块、文件MD5和块序号")
    @PostMapping("/uploadChunk")
    public BaseResponse uploadChunk(
            @RequestParam("file") MultipartFile file,
            @RequestParam("fileMd5") String fileMd5,
            @RequestParam("chunk") int chunk) {

        // 参数校验
        if (file.isEmpty()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传文件不能为空");
        }
        if (chunk < 0) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分块序号不能为负数");
        }

        File tempFile = null;
        try {
            // 创建临时文件（使用更安全的命名方式）
            tempFile = File.createTempFile("upload_" + fileMd5 + "_", "_chunk" + chunk);

            // 将上传文件内容复制到临时文件
            file.transferTo(tempFile);

            // 调用服务层处理分块上传
            return bizMediaFileService.uploadChunk(fileMd5, chunk, tempFile.getAbsolutePath());

        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件上传失败");
        } finally {
            // 确保临时文件被删除
            if (tempFile != null && tempFile.exists()) {
                try {
                    Files.delete(tempFile.toPath());
                } catch (IOException e) {
                    log.error("删除临时文件失败: {}", tempFile.getAbsolutePath(), e);
                }
            }
        }
    }

    @Operation(summary = "合并文件", description = "合并文件")
    @PostMapping("/mergeChunks")
    public BaseResponse mergeChunks(@RequestParam("fileMd5") String fileMd5,
                                    @RequestParam("fileName") String fileName,
                                    @RequestParam("chunkTotal") int chunkTotal) throws Exception {
        UploadFileParamsDto uploadFileParamsDto = new UploadFileParamsDto();
        uploadFileParamsDto.setFileType(1);
        uploadFileParamsDto.setRemark("");
        uploadFileParamsDto.setFileName(fileName);

        return bizMediaFileService.mergeChunks(fileMd5, chunkTotal, uploadFileParamsDto);

    }

    @GetMapping("/getMediaFileList")
    public PageResponse<BizMediaFile> getMediaFileList(VideoPageListVo videoPageListVo) {
        return bizMediaFileService.getMediaFileList(videoPageListVo);
    }


    @PostMapping("/deleteVideoById")
    public BaseResponse<Boolean> deleteVideoById(@RequestBody DeleteRequest deleteRequest) {
        return bizMediaFileService.deleteVideoById(deleteRequest);
    }

    @GetMapping("/getMediaFileById")
    public BaseResponse<BizMediaFile> getMediaFileById(Integer id) {
        return bizMediaFileService.getMediaFileById(id);
    }
}
